#pragma once
#include "util.hpp"
#include <mutex>
#include <assert.h>

// 用户信息管理模块
class user_table
{
public:
    user_table(const std::string &host, const std::string &username,
               const std::string &password, const std::string &dbname, uint16_t port = 3306)
    {
        _mysql = mysql_util::mysql_create(host, username, password, dbname, port);
        assert(_mysql);
    }
    // 注册时的新增用户
    bool insert(Json::Value &user)
    {
#define INSERT_USER "insert user values(null,'%s',password('%s'),1000,0,0);" // 这里的password是加密处理
        if (user["username"].isNull() || user["password"].isNull())
        {
            DBG_LOG("请输入username或者username");
            return false;
        }
        Json::Value val;
        if (select_by_name(user["username"].asCString(), val))
        {
            // 用户已经存在
            DBG_LOG("%s 已经存在，请勿重复添加", user["username"].asCString());
            return false;
        }

        char sql[4096] = {0};
        sprintf(sql, INSERT_USER, user["username"].asCString(), user["password"].asCString());
        bool ret = mysql_util::mysql_exec(_mysql, sql);
        if (!ret)
        {
            DBG_LOG("insert user info failed!!");
            return false;
        }
        else
        {
            DBG_LOG("insert user info success");
            return true;
        }
    }
    // 登录验证，返回详细的用户信息
    bool login(Json::Value &user)
    {
        // 以用户名和密码来作为过滤信息
#define LOGIN "select id,score,total_count,win_count from user where username='%s' and password=password('%s');"
        char sql[4096];
        sprintf(sql, LOGIN, user["username"].asCString(), user["password"].asCString());
        MYSQL_RES *res;

        {
            std::unique_lock<std::mutex> lock(_mutex);
            bool ret = mysql_util::mysql_exec(_mysql, sql);
            if (!ret)
            {
                DBG_LOG("login user info failed!!");
                return false;
            }
            // 用户名不能重复，没有就是没有，有的话只能有一个,这里还是去处理一下
            // 获取结果集
            res = mysql_store_result(_mysql);
            if (!res)
            {
                DBG_LOG("没有用户信息");
                return false;
            }
        }

        int row_num = mysql_num_rows(res);
        if (row_num != 1)
        {
            DBG_LOG("查询的用户信息不唯一或者密码错误");
            return false;
        }

        MYSQL_ROW row = mysql_fetch_row(res);
        user["id"] = static_cast<Json::UInt64>(std::stol(row[0]));
        user["score"] = static_cast<Json::UInt64>(std::stol(row[1]));
        user["total_count"] = std::stoi(row[2]);
        user["win_count"] = std::stoi(row[3]);

        // 释放结果集
        mysql_free_result(res);
        return true;
    }
    // 通过用户名查信息
    //     bool select_by_name(const std::string &name, Json::Value &user)
    //     {
    // #define USER_BY_NAME "select id, score, total_count, win_count from user where username='%s';"
    //         char sql[4096] = {0};
    //         sprintf(sql, USER_BY_NAME, name.c_str());
    //         MYSQL_RES *res = NULL;
    //         {
    //             std::unique_lock<std::mutex> lock(_mutex);
    //             bool ret = mysql_util::mysql_exec(_mysql, sql);
    //             if (ret == false)
    //             {
    //                 DBG_LOG("get user by name failed!!\n");
    //                 return false;
    //             }
    //             // 按理说要么有数据，要么没有数据，就算有数据也只能有一条数据
    //             res = mysql_store_result(_mysql);
    //             if (res == NULL)
    //             {
    //                 DBG_LOG("have no user info!!");
    //                 return false;
    //             }
    //         }
    //         int row_num = mysql_num_rows(res);
    //         if (row_num != 1)
    //         {
    //             DBG_LOG("the user information queried is not unique!!");
    //             return false;
    //         }
    //         MYSQL_ROW row = mysql_fetch_row(res);
    //         user["id"] = (Json::UInt64)std::stol(row[0]);
    //         user["username"] = name;
    //         user["score"] = (Json::UInt64)std::stol(row[1]);
    //         user["total_count"] = std::stoi(row[2]);
    //         user["win_count"] = std::stoi(row[3]);
    //         mysql_free_result(res);
    //         return true;
    //     }
    bool select_by_name(const std::string &name, Json::Value &user)
    {
#define SELECT_BY_NAME "select id,score,total_count,win_count from user where username='%s';"
        char sql[4096];
        sprintf(sql, SELECT_BY_NAME, name.c_str());
        MYSQL_RES *res;
        {
            std::unique_lock<std::mutex> lock(_mutex);
            bool ret = mysql_util::mysql_exec(_mysql, sql);
            if (!ret)
            {
                DBG_LOG("select_by_name error...");
                return false;
            }
            // 用户名不能重复，没有就是没有，有的话只能有一个,这里还是去处理一下
            // 获取结果集
            res = mysql_store_result(_mysql);
            if (!res)
            {
                DBG_LOG("没有用户信息");
                return false;
            }
        }
        int row_num = mysql_num_rows(res);
        if (row_num != 1)
        {
            DBG_LOG("查询的用户信息不唯一");
            return false;
        }

        MYSQL_ROW row = mysql_fetch_row(res);
        user["id"] = static_cast<Json::UInt64>(std::stol(row[0]));
        user["username"] = name;
        user["score"] = static_cast<Json::UInt64>(std::stol(row[1]));
        user["total_count"] = std::stoi(row[2]);
        user["win_count"] = std::stoi(row[3]);

        // 释放结果集
        mysql_free_result(res);
        return true;
    }
    // 通过id查信息
    bool select_by_id(uint64_t id, Json::Value &user)
    {
#define SELECT_BY_ID "select username,score,total_count,win_count from user where id=%ld;"
        char sql[4096];
        sprintf(sql, SELECT_BY_ID, id);
        MYSQL_RES *res;

        {
            std::unique_lock<std::mutex> lock(_mutex);
            bool ret = mysql_util::mysql_exec(_mysql, sql);
            if (!ret)
            {
                DBG_LOG("select_by_id error...");
                return false;
            }
            // 用户名不能重复，没有就是没有，有的话只能有一个,这里还是去处理一下
            // 获取结果集
            res = mysql_store_result(_mysql);
            if (!res)
            {
                DBG_LOG("没有用户信息");
                return false;
            }
        }
        int row_num = mysql_num_rows(res);
        if (row_num != 1)
        {
            DBG_LOG("查询的用户信息不唯一");
            return false;
        }

        MYSQL_ROW row = mysql_fetch_row(res);
        user["id"] = static_cast<Json::UInt64>(id);
        user["username"] = row[0];
        user["score"] = static_cast<Json::UInt64>(std::stol(row[1]));
        user["total_count"] = std::stoi(row[2]);
        user["win_count"] = std::stoi(row[3]);

        // 释放结果集
        mysql_free_result(res);
        return true;
    }
    // 赢的话天梯分数增加30，胜场加一，总场次加一
    bool win(uint64_t id)
    {
#define WIN "update user set score=score+30,total_count=total_count+1,win_count=win_count+1 where id=%ld;"
        char sql[4096] = {0};
        sprintf(sql, WIN, id);
        bool ret = mysql_util::mysql_exec(_mysql, sql);
        if (!ret)
        {
            DBG_LOG("赢更新错误...");
            return false;
        }
        return true;
    }
    // 输的话天梯分数减少30，总场次加一，其他不变
    bool lose(uint64_t id)
    {
#define LOSE "update user set score=score+30,total_count=total_count+1 where id=%ld;"
        char sql[4096] = {0};
        sprintf(sql, LOSE, id);
        bool ret = mysql_util::mysql_exec(_mysql, sql);
        if (!ret)
        {
            DBG_LOG("败更新错误...");
            return false;
        }
        return true;
    }
    ~user_table()
    {
        mysql_util::mysql_destory(_mysql);
        _mysql = nullptr;
    }

private:
    MYSQL *_mysql;
    std::mutex _mutex;
};


// #ifndef __M_DB_H__
// #define __M_DB_H__
// #include "util.hpp"
// #include <mutex>
// #include <cassert>

// class user_table{
//    private:
//           MYSQL *_mysql; //mysql操作句柄
//           std::mutex _mutex;//互斥锁保护数据库的访问操作
//    public:
//           user_table(const std::string &host,
//                const std::string &username,
//                const std::string &password,
//                const std::string &dbname,
//                uint16_t port = 3306) {
//                _mysql = mysql_util::mysql_create(host, username, password, dbname, port);
//                assert(_mysql != NULL);
//           }
//           ~user_table() {
//                mysql_util::mysql_destory(_mysql);
//                _mysql = NULL;
//           }
//           //注册时新增用户
//           bool insert(Json::Value &user) {
// #define INSERT_USER "insert user values(null, '%s', '%s', 1000, 0, 0);"
//                // sprintf(void *buf, char *format, ...)
//                if (user["password"].isNull() || user["username"].isNull()) {
//                     DBG_LOG("INPUT PASSWORD OR USERNAME");
//                     return false;
//                }
//                char sql[4096] = {0};
//                sprintf(sql, INSERT_USER, user["username"].asCString(), user["password"].asCString());
//                bool ret = mysql_util::mysql_exec(_mysql, sql);
//                if (ret == false) {
//                     DBG_LOG("insert user info failed!!\n");
//                     return false;
//                }
//                return true;
//           }
//           //登录验证，并返回详细的用户信息
//           bool login(Json::Value &user) {
//                if (user["password"].isNull() || user["username"].isNull()) {
//                     DBG_LOG("INPUT PASSWORD OR USERNAME");
//                     return false;
//                }
//                //以用户名和密码共同作为查询过滤条件，查询到数据则表示用户名密码一致，没有信息则用户名密码错误
// #define LOGIN_USER "select id, score, total_count, win_count from user where username='%s' and password='%s';"
//                char sql[4096] = {0};
//                sprintf(sql, LOGIN_USER, user["username"].asCString(), user["password"].asCString());
//                MYSQL_RES *res = NULL;
//                {
//                     std::unique_lock<std::mutex> lock(_mutex);
//                     bool ret = mysql_util::mysql_exec(_mysql, sql);
//                     if (ret == false) {
//                          DBG_LOG("user login failed!!\n");
//                          return false;
//                     }
//                     //按理说要么有数据，要么没有数据，就算有数据也只能有一条数据
//                     res = mysql_store_result(_mysql);
//                     if (res == NULL) {
//                          DBG_LOG("have no login user info!!");
//                          return false;
//                     }
//                }
//                int row_num = mysql_num_rows(res);
//                if (row_num != 1) {
//                     DBG_LOG("the user information queried is not unique!!");
//                     return false;
//                }
//                MYSQL_ROW row = mysql_fetch_row(res);
//                user["id"] = (Json::UInt64)std::stol(row[0]);
//                user["score"] = (Json::UInt64)std::stol(row[1]);
//                user["total_count"] = std::stoi(row[2]);
//                user["win_count"] = std::stoi(row[3]);
//                mysql_free_result(res);
//                return true;
//           }
//           // 通过用户名获取用户信息
//           bool select_by_name(const std::string &name, Json::Value &user) {
// #define USER_BY_NAME "select id, score, total_count, win_count from user where username='%s';"
//                char sql[4096] = {0};
//                sprintf(sql, USER_BY_NAME, name.c_str());
//                MYSQL_RES *res = NULL;
//                {
//                     std::unique_lock<std::mutex> lock(_mutex);
//                     bool ret = mysql_util::mysql_exec(_mysql, sql);
//                     if (ret == false) {
//                          DBG_LOG("get user by name failed!!\n");
//                          return false;
//                     }
//                     //按理说要么有数据，要么没有数据，就算有数据也只能有一条数据
//                     res = mysql_store_result(_mysql);
//                     if (res == NULL) {
//                          DBG_LOG("have no user info!!");
//                          return false;
//                     }
//                }
//                int row_num = mysql_num_rows(res);
//                if (row_num != 1) {
//                     DBG_LOG("the user information queried is not unique!!");
//                     return false;
//                }
//                MYSQL_ROW row = mysql_fetch_row(res);
//                user["id"] = (Json::UInt64)std::stol(row[0]);
//                user["username"] = name;
//                user["score"] = (Json::UInt64)std::stol(row[1]);
//                user["total_count"] = std::stoi(row[2]);
//                user["win_count"] = std::stoi(row[3]);
//                mysql_free_result(res);
//                return true;
//           }
//           // 通过用户名获取用户信息
//           bool select_by_id(uint64_t id, Json::Value &user) {
// #define USER_BY_ID "select username, score, total_count, win_count from user where id=%d;"
//                char sql[4096] = {0};
//                sprintf(sql, USER_BY_ID, id);
//                MYSQL_RES *res = NULL;
//                {
//                     std::unique_lock<std::mutex> lock(_mutex);
//                     bool ret = mysql_util::mysql_exec(_mysql, sql);
//                     if (ret == false) {
//                          DBG_LOG("get user by id failed!!\n");
//                          return false;
//                     }
//                     //按理说要么有数据，要么没有数据，就算有数据也只能有一条数据
//                     res = mysql_store_result(_mysql);
//                     if (res == NULL) {
//                          DBG_LOG("have no user info!!");
//                          return false;
//                     }
//                }
//                int row_num = mysql_num_rows(res);
//                if (row_num != 1) {
//                     DBG_LOG("the user information queried is not unique!!");
//                     return false;
//                }
//                MYSQL_ROW row = mysql_fetch_row(res);
//                user["id"] = (Json::UInt64)id;
//                user["username"] = row[0];
//                user["score"] = (Json::UInt64)std::stol(row[1]);
//                user["total_count"] = std::stoi(row[2]);
//                user["win_count"] = std::stoi(row[3]);
//                mysql_free_result(res);
//                return true;
//           }
//           //胜利时天梯分数增加30分，战斗场次增加1，胜利场次增加1
//           bool win(uint64_t id) {
// #define USER_WIN "update user set score=score+30, total_count=total_count+1, win_count=win_count+1 where id=%d;"
//                char sql[4096] = {0};
//                sprintf(sql, USER_WIN, id);
//                bool ret = mysql_util::mysql_exec(_mysql, sql);
//                if (ret == false) {
//                     DBG_LOG("update win user info failed!!\n");
//                     return false;
//                }
//                return true;
//           }
//           //失败时天梯分数减少30，战斗场次增加1，其他不变
//           bool lose(uint64_t id) {
// #define USER_LOSE "update user set score=score-30, total_count=total_count+1 where id=%d;"
//                char sql[4096] = {0};
//                sprintf(sql, USER_LOSE, id);
//                bool ret = mysql_util::mysql_exec(_mysql, sql);
//                if (ret == false) {
//                     DBG_LOG("update lose user info failed!!\n");
//                     return false;
//                }
//                return true;
//           }
// };
// #endif
